home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cmdline.lha / cmdline / src / lib / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  5.1 KB  |  188 lines

  1. //------------------------------------------------------------------------
  2. // ^FILE: parse.c - parsing portion of the CmdLine library
  3. //
  4. // ^DESCRIPTION:
  5. //     The following functions defined in <cmdline.h> are implemented:
  6. //
  7. //        CmdLine::prologue() -- initialize stuff for parsing
  8. //        CmdLine::epilogue() -- finish up stuff for parsing
  9. //        CmdLine::parse()     -- parse arguments from an iterator
  10. //
  11. // ^HISTORY:
  12. //    12/05/91    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  13. //
  14. //    03/01/93    Brad Appleton    <brad@ssd.csd.harris.com>
  15. //    - Added cmd_nargs_parsed field to CmdLine
  16. //    - Added exit_handler() and quit() member-functions to CmdLine
  17. //-^^---------------------------------------------------------------------
  18.  
  19. #include <stdlib.h>
  20. #include <iostream.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23.  
  24. #include "exits.h"
  25. #include "states.h"
  26. #include "arglist.h"
  27. #include "cmdline.h"
  28.  
  29.  
  30. //-------
  31. // ^FUNCTION: CmdLine::prologue - initialize before parsing
  32. //
  33. // ^SYNOPSIS:
  34. //    unsigned CmdLine::prologue(void)
  35. //
  36. // ^PARAMETERS:
  37. //    None.
  38. //
  39. // ^DESCRIPTION:
  40. //    Before we can begin parsing argument from the command-line, we need
  41. //    to set (or reset) certain attributes of the CmdLine object. Among
  42. //    other things, we need to reset its state and status, and we need to
  43. //    reset the state of each of its arguments.
  44. //
  45. // ^REQUIREMENTS:
  46. //    None.
  47. //
  48. // ^SIDE-EFFECTS:
  49. //    Modifies all parts of the CmdLine object and its arguments.
  50. //
  51. // ^RETURN-VALUE:
  52. //    A combination of bitmasks of type CmdLine::CmdStatus corresponding to
  53. //    what (if anything) went wrong.
  54. //
  55. // ^ALGORITHM:
  56. //    Follow along - its not too complicated.
  57. //-^^----
  58. unsigned
  59. CmdLine::prologue(void)
  60. {
  61.    // reset parse-specific attributes
  62.    cmd_parse_state = cmd_START_STATE ;
  63.    cmd_state = 0 ;
  64.    cmd_status = NO_ERROR ;
  65.    cmd_nargs_parsed = 0 ;
  66.  
  67.    // reset parse-specific attributes for each argument
  68.    CmdArgListListIter  list_iter(cmd_args);
  69.    for (CmdArgList * alist = list_iter() ; alist ; alist = list_iter()) {
  70.       CmdArgListIter  iter(alist);
  71.       for (CmdArg * cmdarg = iter() ; cmdarg ; cmdarg = iter()) {
  72.          cmdarg->clear();
  73.       }
  74.    }
  75.  
  76.    return  cmd_status ;
  77. }
  78.  
  79. //-------
  80. // ^FUNCTION: CmdLine::epilogue - clean up after parsing
  81. //
  82. // ^SYNOPSIS:
  83. //    unsigned CmdLine::epilogue(void)
  84. //
  85. // ^PARAMETERS:
  86. //    None.
  87. //
  88. // ^DESCRIPTION:
  89. //
  90. // ^REQUIREMENTS:
  91. //    None.
  92. //
  93. // ^SIDE-EFFECTS:
  94. //    Modifies the command-line obejct.
  95. //
  96. //    Prints messages on cerr (if QUIET is not set) if there are
  97. //    missing required arguments or values (and prompts for them if
  98. //    PROMPT_USER is set of $PROMPT_USER is exists and is non-empty).
  99. //
  100. //    Prints a usage message if there were syntax error.
  101. //
  102. //    Terminates program execution by calling quit(e_SYNTAX) if
  103. //    (NO_ABORT is NOT set and the command-status is NOT NO_ERROR).
  104. //
  105. // ^RETURN-VALUE:
  106. //    A combination of bitmasks of type CmdLine::CmdStatus corresponding to
  107. //    what (if anything) went wrong.
  108. //
  109. // ^ALGORITHM:
  110. //    - See if we left an argument dangling without a required value,
  111. //    - Check for missing required arguments
  112. //    - Print usage if required
  113. //    - Exit if required
  114. //-^^----
  115. unsigned
  116. CmdLine::epilogue(void)
  117. {
  118.    if (cmd_err == NULL)  cmd_err = &cerr;
  119.  
  120.    // see if we left an argument dangling without a value
  121.    ck_need_val() ;
  122.  
  123.    // check for any missing required arguments
  124.    cmd_status |= missing_args();
  125.  
  126.    // print usage if necessary
  127.    if (cmd_status & ARG_MISSING) {
  128.       usage();
  129.       quit(e_SYNTAX);
  130.    } else if (cmd_status && (! (cmd_flags & NO_ABORT))) {
  131.       usage();
  132.       quit(e_SYNTAX);
  133.    }
  134.  
  135.    return  cmd_status ;
  136. }
  137.  
  138. //-------------------
  139. // ^FUNCTION: parse - parse arguments from an iterator
  140. //
  141. // ^SYNOPSIS:
  142. //    parse(arg_iter, auto_processing)
  143. //
  144. // ^PARAMETERS:
  145. //    CmdLineArgIter & arg_iter;
  146. //    -- collection of string arguments from the command-line
  147. //
  148. //    int  auto_processing;
  149. //    -- if this is NON-zero, then automatically call prologue() and
  150. //       epilogue() to do pre- and post- processing.
  151. //
  152. // ^DESCRIPTION:
  153. //    Parse all the argument in a given argument iterator.
  154. //    If auto_processing is NON-zero then the programmer is
  155. //    directly responsible for calling prologue() and epilogue().
  156. //
  157. // ^REQUIREMENTS:
  158. //    None.
  159. //
  160. // ^SIDE-EFFECTS:
  161. //    - Uses up all remaining arguments in arg_iter
  162. //    - Modifies the CmdLine
  163. //
  164. // ^RETURN-VALUE:
  165. //    The resultant status of the CmdLine:
  166. //
  167. // ^ALGORITHM:
  168. //    Trivial - just iterate through calling parse_arg.
  169. //-^^----------------
  170. unsigned
  171. CmdLine::parse(CmdLineArgIter & arg_iter, int  auto_processing)
  172. {
  173.    // NOTE: If arg_iter.is_temporary() is TRUE then we MUST remember
  174.    //       to set the CmdLine::TEMP flags before parsing (and put it
  175.    //       back the way it was when we are finished.
  176.    //
  177.    if (auto_processing)  (void) prologue();
  178.    unsigned  save_flags = cmd_flags;
  179.    if (arg_iter.is_temporary())  cmd_flags |= TEMP;
  180.    for (const char * arg = arg_iter() ; arg ; arg = arg_iter()) {
  181.       (void) parse_arg(arg);
  182.    }
  183.    if (arg_iter.is_temporary())  cmd_flags = save_flags;
  184.    if (auto_processing)  (void) epilogue();
  185.    return  cmd_status ;
  186. }
  187.  
  188.